home *** CD-ROM | disk | FTP | other *** search
/ Meeting Pearls 2 / Meeting Pearls Vol. II (1995)(GTI - Schatztruhe)[!].iso / Pearls / dev / GUI / gengui / Lib / gui_lnk.c next >
C/C++ Source or Header  |  1994-04-29  |  17KB  |  608 lines

  1.  
  2. #include <exec/libraries.h>
  3. #include <stdlib.h>
  4. #include <exec/types.h>
  5. #include <proto/gadtools.h>
  6. #include <libraries/gadtools.h>
  7. #include <proto/intuition.h>
  8. #include <intuition/intuition.h>
  9. #include <proto/graphics.h>
  10. #include <graphics/text.h>
  11. #include <string.h>
  12. #include <intuition/gadgetclass.h>
  13.  
  14. #define GL_VBOX -1
  15. #define GL_HBOX -2
  16. #define CUSTOM_KIND -3
  17.  
  18. #define MODE_NEW     0
  19. #define MODE_RESIZE  1
  20. #define MODE_REFRESH 2
  21. #define MODE_FREE    3
  22. #define MODE_BACKUP  4
  23. #define MODE_RESTORE 5
  24.  
  25. #define BOXFLG_CUSTOM   1
  26. #define BOXFLG_STRING   2
  27. #define BOXFLG_INTEGER  4
  28. #define BOXFLG_DISABLED 8
  29. #define BOXFLG_BACKUP   16
  30. #define BOXFLG_INITED   (1<<15)
  31. #define BOXFLG_SKIPREFRESH (1<<14)
  32.  
  33. #define max(x,y) ((x)>(y)?(x):(y))
  34. #define min(x,y) ((x)<(y)?(x):(y))
  35.  
  36. struct GadDim {
  37.    int Kind;
  38.    USHORT Rx,Ry,Cx,Cy,Px,Py,SRx,SRy,SPx,SPy;
  39.    USHORT Flags;
  40. };
  41.  
  42. struct Box {
  43.    struct GadDim Dim;
  44.    struct Box **Entry;
  45. };
  46.  
  47. struct WinInfo {
  48.    struct Box *Box;
  49.    struct Gadget **Gadgets;
  50.    struct Gadget *Prev;
  51.    struct Window *Window;
  52.    struct Gadget *GList;
  53.    int FontX,FontY;
  54.    struct TextAttr TextAttr;
  55.    APTR Visual;
  56.    char Mode,Render;
  57. //   USHORT MinX,MinY;
  58. };
  59.  
  60. struct GadInfo {
  61.    struct GadDim Dim;
  62.    int XSpace,YSpace,GadNum;
  63.    int (*CustomFunc)(struct WinInfo *WInfo,
  64.                      struct NewGadget *NewGad,
  65.                      struct GadInfo *GadInfo,
  66.                      int Left, int Top, int Width, int Height);
  67.    struct TextAttr *TextAttr;
  68.    char *Text;
  69.    int GadgetID;
  70.    ULONG Flags,UserData;
  71.    int (*HookFunc)(struct IntuiMessage *);
  72.    ULONG *Tags;
  73.    ULONG *SaveTags;
  74.    ULONG Code;
  75.    struct Gadget *ThisGad;
  76. };
  77.  
  78. #define GetString(g) (((struct StringInfo * )g->SpecialInfo)->Buffer)
  79. #define GetNumber(g) (((struct StringInfo * )g->SpecialInfo)->LongInt)
  80. #define GetInfo(g) ((struct GadInfo *)(g->UserData))
  81. #define GetUserData(g) (GetInfo(g)->UserData)
  82.  
  83. ULONG Modify[]={0,0,GTCB_Checked,GTIN_Number,GTLV_Selected,
  84.                           GTMX_Active,0,GTCY_Active,GTPA_Color,
  85.                           GTSC_Top,0,GTSL_Level,GTST_String,0};
  86.  
  87. ULONG Default[]={0,0,FALSE,0,~0,0,0,0,1,0,0,0,(ULONG)"",0};
  88.  
  89. static ULONG *MergeTags(ULONG *oldlist,ULONG *newlist)
  90. {
  91.    ULONG *p;
  92.    if(!oldlist) {
  93.       oldlist=malloc(16*sizeof(ULONG));
  94.       if(!oldlist) return(NULL);
  95.       oldlist[0]=16;
  96.       oldlist[1]=TAG_DONE;
  97.    }
  98.  
  99.    while(*newlist!=TAG_DONE) {
  100.       switch(*newlist) {
  101.          case TAG_IGNORE:  newlist+=2;
  102.                            break;
  103.          case TAG_MORE:    newlist=(ULONG *)newlist[1];
  104.                            break;
  105.          case TAG_SKIP:    newlist+=2*newlist[1]+2;
  106.                            break;
  107.          default:
  108.  
  109.                            p=oldlist+1;
  110.             /* passenden Eintrag in der Taglist suchen, bzw Ende der Liste */
  111.                            while(*p!=TAG_DONE && *p!=*newlist) p+=2;
  112.                            if(*p==*newlist) {
  113.                               p[1]=newlist[1]; // alte Daten ueberschreiben
  114.                               newlist+=2;
  115.                            } else {
  116.                               int n=p-oldlist; // Position im Array;
  117.  
  118.                               if(n>=oldlist[0]-1) { // Array vergrößern
  119.                                  ULONG *mem;
  120.                                  mem=realloc(oldlist,oldlist[0]+16*sizeof(ULONG));
  121.                                  if(!mem) return(NULL);
  122.                                  oldlist=mem;
  123.                                  p=oldlist+n;
  124.                               }
  125.  
  126.                               *p++=*newlist++;
  127.                               *p++=*newlist++;
  128.                               *p++=TAG_DONE;
  129.                            }
  130.                            break;
  131.       }
  132.    }
  133.    return(oldlist);
  134. }
  135.  
  136. BOOL Gui_SetGadgetAttrsA(struct Gadget *gad,struct Window *win,
  137.                        struct Requester *req, ULONG *Tag)
  138. {
  139.    ULONG *newtags;
  140.    struct GadInfo *gi;
  141.  
  142.    gi=GetInfo(gad);
  143.  
  144.    if(!gi->SaveTags) {
  145.       gi->SaveTags=MergeTags(NULL,gi->Tags);
  146.       if(!gi->SaveTags) return(FALSE);
  147.    }
  148.  
  149.    newtags=MergeTags(gi->SaveTags,Tag);
  150.    if(!newtags) return(FALSE);
  151.    gi->SaveTags=newtags;
  152.    GT_SetGadgetAttrsA(gad,win,req,(struct TagItem *)Tag);
  153.    return(TRUE);
  154. }
  155. BOOL Gui_SetGadgetAttrs(struct Gadget *gad,struct Window *win,
  156.                        struct Requester *req, ULONG Tag1,...)
  157. {
  158.    return(Gui_SetGadgetAttrsA(gad,win,req,&Tag1));
  159. }
  160.  
  161. int MakeGTGadget(struct WinInfo *winfo,                              ///
  162.                             struct GadInfo *gad,
  163.                             int left, int top, int width, int height)
  164. {
  165.    struct NewGadget ng;
  166.  
  167.    if(winfo->Mode==MODE_REFRESH && gad->Dim.Kind>=0) return(0);
  168.  
  169.    ng.ng_LeftEdge=left + (gad->XSpace>>1);
  170.    ng.ng_TopEdge=top + (gad->YSpace>>1);
  171.    ng.ng_Width=width - gad->XSpace;
  172.    ng.ng_Height=height - gad->YSpace;
  173.    ng.ng_GadgetText=gad->Text;
  174.    ng.ng_TextAttr=gad->TextAttr ? gad->TextAttr : &winfo->TextAttr;
  175.    ng.ng_GadgetID=gad->GadgetID;
  176.    ng.ng_Flags=gad->Flags;
  177.    ng.ng_VisualInfo=winfo->Visual;
  178.    ng.ng_UserData=(void *)gad;
  179.  
  180.    gad->Dim.Flags|=BOXFLG_INITED;
  181.  
  182.    if(gad->Dim.Kind>=0) {
  183.       // Falls dies kein erneutes aufsetzen ist: SaveTags neu errechnen
  184.       if(!(winfo->Box->Dim.Flags & BOXFLG_BACKUP) && winfo->Mode==MODE_NEW) {
  185.          ULONG *tags;
  186.          static ULONG modifytag[]={0,0,TAG_DONE};
  187.  
  188.          if(gad->SaveTags) free(gad->SaveTags);
  189.          gad->SaveTags=NULL;
  190.  
  191.          if(Modify[gad->Dim.Kind]) {
  192.             modifytag[0]=Modify[gad->Dim.Kind];
  193.             modifytag[1]=Default[gad->Dim.Kind];
  194.             tags=MergeTags(NULL,modifytag);
  195.             if(!tags) return(1);
  196.             gad->SaveTags=tags;
  197.          }
  198.          tags=MergeTags(gad->SaveTags,gad->Tags);
  199.          if(!tags) return(1);
  200.          gad->SaveTags=tags;
  201.       }
  202.  
  203.       winfo->Prev=gad->ThisGad=winfo->Gadgets[gad->GadNum]=
  204.           CreateGadgetA(gad->Dim.Kind,winfo->Prev,&ng,(struct TagItem *)(gad->SaveTags+1));
  205.       if(winfo->Prev==NULL) return(1); else return(0);
  206.    } else {
  207.       return(gad->CustomFunc(winfo,&ng,gad,left,top,width,height));
  208.    }
  209. } ///
  210. static int MakeGuiGadget(struct WinInfo *winfo,                      ///
  211.                           struct Box *box,
  212.                           int left,int top,int width,int height)
  213. {
  214.    struct Box **p;
  215.    int relx=0,rely=0,absx=0,absy=0;
  216.    int w,h;
  217.  
  218.    if(box->Dim.Kind>0 || box->Dim.Kind==CUSTOM_KIND)
  219.                          return(MakeGTGadget(winfo,(struct GadInfo *)box,
  220.                                                  left,top,width,height));
  221.  
  222.    if(!box->Entry) return(0);
  223.  
  224.    relx=box->Dim.SRx;
  225.    rely=box->Dim.SRy;
  226.    absx=box->Dim.SPx;
  227.    absy=box->Dim.SPy;
  228.  
  229.    if(!winfo->Render) {
  230.       for(p=box->Entry;*p;p++) {
  231.          if(MakeGuiGadget(winfo,(*p),0,0,0,0)) return(1);
  232.       }
  233.    } else {
  234.       if(box->Dim.Kind==GL_HBOX) {
  235.  
  236.          width-=absx;
  237.          if(width<0) width=0;
  238.  
  239.          for(w=0,p=box->Entry;*p;p++) {
  240.             w=width * ((*p)->Dim.Rx)/relx + (*p)->Dim.Px;
  241.             h=height * ((*p)->Dim.Ry)/rely + (*p)->Dim.Py;
  242.  
  243.             if(MakeGuiGadget(winfo,(*p),left,top,w,h)) return(1);
  244.  
  245.             left+=w;
  246.          }
  247.  
  248.       } else {
  249.  
  250.          height-=absy;
  251.          if(height<0) height=0;
  252.  
  253.          for(w=0,p=box->Entry;*p;p++) {
  254.             w=width * ((*p)->Dim.Rx)/relx + (*p)->Dim.Px;
  255.             h=height * ((*p)->Dim.Ry)/rely + (*p)->Dim.Py;
  256.  
  257.             if(MakeGuiGadget(winfo,(*p),left,top,w,h)) return(1);
  258.  
  259.             top+=h;
  260.          }
  261.  
  262.       }
  263.    }
  264.    return(0);
  265. }          ///
  266.  
  267. static void InitGui(struct WinInfo *winfo,struct Box *box)           ///
  268. {
  269.    struct Box **p;
  270.    int relx=0,rely=0,absx=0,absy=0;
  271.  
  272.    box->Dim.Px+=box->Dim.Cx*winfo->FontX;
  273.    box->Dim.Py+=box->Dim.Cy*winfo->FontY;
  274.    box->Dim.Cx=0;
  275.    box->Dim.Cy=0;
  276.  
  277.    if(!box->Entry || box->Dim.Kind>0 || box->Dim.Kind==CUSTOM_KIND) {
  278.       return;
  279.    }
  280.  
  281.    for(p=box->Entry;*p;p++) InitGui(winfo,*p);
  282.  
  283.    if(box->Dim.Kind==GL_HBOX) {
  284.  
  285.       for(p=box->Entry;*p;p++) {
  286.          relx+=(*p)->Dim.Rx;
  287.          absx+=(*p)->Dim.Px;
  288.  
  289.          rely=max(rely,(*p)->Dim.Ry);
  290.          absy=max(absy,(*p)->Dim.Py);
  291.       }
  292.    } else {
  293.       for(p=box->Entry;*p;p++) {
  294.          rely+=(*p)->Dim.Ry;
  295.          absy+=(*p)->Dim.Py;
  296.  
  297.          relx=max(relx,(*p)->Dim.Rx);
  298.          absx=max(absx,(*p)->Dim.Px);
  299.       }
  300.    }
  301.  
  302.    if(relx==0) relx=1;
  303.    if(rely==0) rely=1;
  304.  
  305.    box->Dim.SRx=relx;
  306.    box->Dim.SRy=rely;
  307.    box->Dim.SPx=absx;
  308.    box->Dim.SPy=absy;
  309.  
  310.    box->Dim.Flags=BOXFLG_INITED;
  311.    for(p=box->Entry;*p;p++) {
  312.       box->Dim.Flags|=(*p)->Dim.Flags;
  313.    }
  314.  
  315.    return;
  316. }          ///
  317. static int BackupGui(struct WinInfo *winfo,struct Box *box)          ///
  318. {
  319.    struct GadInfo *gad=(struct GadInfo *)box;
  320.    int err=0;
  321.  
  322.    if(box->Dim.Flags & (BOXFLG_STRING | BOXFLG_INTEGER)) {
  323.  
  324.       if(box->Dim.Kind==INTEGER_KIND) {
  325.          ULONG tags[]={GTIN_Number,0,TAG_DONE};
  326.          tags[1]=GetNumber(gad->ThisGad);
  327.          MergeTags(gad->SaveTags,tags);
  328. //         gad->Code=GetNumber(gad->ThisGad);
  329.       } else if(box->Dim.Kind==STRING_KIND) {
  330.          ULONG tags[]={GTST_String,0,TAG_DONE};
  331.          if(gad->Code) free((void *)gad->Code);
  332.          gad->Code=(ULONG)strdup(GetString(gad->ThisGad));
  333.          if(!gad->Code) return(1);
  334.          tags[1]=gad->Code;
  335.          MergeTags(gad->SaveTags,tags); // This is always successful, since
  336.                                         // there is always a GTST_String tag
  337.                                         // in the taglist (see MakeGTGadget)
  338.       } else if(box->Dim.Kind==GL_VBOX || box->Dim.Kind==GL_HBOX) {
  339.          struct Box **p;
  340.  
  341.          if(!box->Entry) return(0);
  342.  
  343.          for(p=box->Entry; *p; p++) {
  344.             err|=BackupGui(winfo,*p);
  345.          }
  346.       }
  347.    }
  348.    return(err);
  349. } ///
  350. static void FindCustom(struct WinInfo *winfo,struct Box *box)        ///
  351. {
  352.    struct GadInfo *gad=(struct GadInfo *)box;
  353.    static struct NewGadget ng; /* Just to avoid Enforcer Hits */
  354.  
  355.    if( !(box->Dim.Flags & BOXFLG_CUSTOM)) return;
  356.  
  357.    if(box->Dim.Kind==CUSTOM_KIND) {
  358.       gad->CustomFunc(winfo,&ng,gad,0,0,0,0);
  359.    } else if(box->Dim.Kind==GL_VBOX || box->Dim.Kind==GL_HBOX) {
  360.       struct Box **p;
  361.  
  362.       if(box->Dim.Flags & BOXFLG_CUSTOM) {
  363.          if(!box->Entry) return;
  364.  
  365.          for(p=box->Entry; *p; p++) {
  366.             FindCustom(winfo,*p);
  367.          }
  368.       }
  369.    }
  370. } ///
  371.  
  372. struct IntuiMessage *Gui_GetIMsg(struct MsgPort *userport,struct IntuiMessage *imsg) ///
  373. {
  374.    struct IntuiMessage *msg;
  375.    int ignore=0;
  376.    struct Gadget *gad;
  377.  
  378.    if(msg=GT_GetIMsg(userport)) {
  379.       *imsg=*msg;
  380.       GT_ReplyIMsg(msg);
  381.  
  382.       switch(imsg->Class) {
  383.          case IDCMP_MOUSEMOVE:
  384.          case IDCMP_GADGETUP:
  385.          case IDCMP_GADGETDOWN:
  386.             gad=(struct Gadget *)imsg->IAddress;
  387.             if(gad && gad->GadgetID>=0) {
  388.                struct GadInfo *gi;
  389.                ULONG tags[]={0,0,TAG_DONE};
  390.                gi=GetInfo(gad);
  391.  
  392.                if(Modify[gi->Dim.Kind]) {
  393.                   tags[0]=Modify[gi->Dim.Kind];
  394.                   tags[1]=imsg->Code;
  395.                   MergeTags(gi->SaveTags,tags); //always successful in this case
  396.                }
  397.                if(GetInfo(gad)->HookFunc) ignore=GetInfo(gad)->HookFunc(imsg);
  398.             }
  399.             break;
  400.       }
  401.       if(!ignore) return(imsg);
  402.    }
  403.    return(NULL);
  404. } ///
  405.  
  406. void ClearWindow(struct Window *win)
  407. {
  408.    RefreshWindowFrame(win);
  409.    EraseRect(win->RPort,win->BorderLeft,
  410.                         win->BorderTop,
  411.                         win->Width-1-win->BorderRight,
  412.                         win->Height-1-win->BorderBottom);
  413. }
  414.  
  415. int RenderGui(struct Window *win, struct WinInfo *winfo)             ///
  416. {
  417.    winfo->Window=win;
  418.    winfo->Mode=MODE_NEW;
  419.    winfo->Render=1;
  420.  
  421.    AskFont(win->RPort,&winfo->TextAttr);
  422.  
  423.    winfo->FontX = win->RPort->Font->tf_XSize;
  424.    winfo->FontY = win->RPort->Font->tf_YSize;
  425.    winfo->Visual=GetVisualInfoA(win->WScreen,NULL);
  426.  
  427.    if(!(winfo->Box->Dim.Flags & BOXFLG_INITED)) {
  428.       InitGui(winfo,winfo->Box);
  429.       winfo->Box->Dim.Flags|=BOXFLG_INITED;
  430.    }
  431.  
  432.    if(!winfo->Visual) goto exit_fail2;
  433.  
  434.    if(!CreateContext(&winfo->GList)) return(1);
  435.  
  436.    winfo->Prev=winfo->GList;
  437.  
  438.    if(MakeGuiGadget(winfo,winfo->Box,win->BorderLeft,win->BorderTop,
  439.                      win->Width - win->BorderLeft - win->BorderRight,
  440.                      win->Height - win->BorderTop - win->BorderBottom))
  441.                                                              goto exit_fail3;
  442.    AddGList(win,winfo->GList,-1,-1,NULL);
  443.    RefreshGList(winfo->GList,win,NULL,-1);
  444.    GT_RefreshWindow(win,NULL);
  445.  
  446.    if(winfo->Box->Dim.Flags & BOXFLG_BACKUP) {
  447.       winfo->Mode=MODE_RESTORE;
  448.       FindCustom(winfo,winfo->Box);
  449.       winfo->Box->Dim.Flags &= ~BOXFLG_BACKUP;
  450.    }
  451.  
  452.    return(0);
  453.  
  454. exit_fail3:
  455.    if(winfo->GList) FreeGadgets(winfo->GList);
  456.    FreeVisualInfo(winfo->Visual);
  457. exit_fail2:
  458.    return(1);
  459. }  ///
  460. int ResizeGui(struct WinInfo *winfo)                                 ///
  461. {
  462.    struct Window *win=winfo->Window;
  463.  
  464.    winfo->Box->Dim.Flags|=BOXFLG_SKIPREFRESH;
  465.    winfo->Mode=MODE_BACKUP;
  466.    winfo->Render=0;
  467.  
  468.    ClearWindow(win);
  469.  
  470.    FindCustom(winfo,winfo->Box); // Backup od customgadgets
  471.  
  472.    BackupGui(winfo,winfo->Box);
  473.  
  474.    winfo->Mode=MODE_RESIZE;
  475.    winfo->Render=1;
  476.  
  477.    if(winfo->GList) {
  478.       RemoveGList(win,winfo->GList,-1);
  479.       FreeGadgets(winfo->GList);
  480.    }
  481.    winfo->GList=NULL;
  482.  
  483.    ClearWindow(win);
  484.  
  485.    if(!CreateContext(&winfo->GList)) return(1);
  486.    winfo->Prev=winfo->GList;
  487.  
  488.    if(MakeGuiGadget(winfo,winfo->Box,win->BorderLeft,win->BorderTop,
  489.                      win->Width - win->BorderLeft - win->BorderRight,
  490.                      win->Height - win->BorderTop - win->BorderBottom))
  491.                                                                   return(2);
  492.  
  493.    AddGList(win,winfo->GList,-1,-1,NULL);
  494.    RefreshGList(winfo->GList,win,NULL,-1);
  495.    GT_RefreshWindow(win,NULL);
  496.    winfo->Mode=MODE_RESTORE;
  497.    winfo->Render=0;
  498.    FindCustom(winfo,winfo->Box);
  499.    return(0);
  500. }  ///
  501. int RefreshGui(struct WinInfo *winfo)                                ///
  502. {
  503.    struct Window *win=winfo->Window;
  504.  
  505.    if(winfo->Box->Dim.Flags&BOXFLG_SKIPREFRESH) {
  506.       winfo->Box->Dim.Flags&=~BOXFLG_SKIPREFRESH;
  507.       return(0);
  508.    }
  509.  
  510.    winfo->Render=1;
  511.    winfo->Mode=MODE_REFRESH;
  512.    if(MakeGuiGadget(winfo,winfo->Box,win->BorderLeft,win->BorderTop,
  513.                     win->Width - win->BorderLeft - win->BorderRight,
  514.                     win->Height - win->BorderTop - win->BorderBottom)) return(1);
  515.  
  516.    RefreshGList(winfo->GList,win,NULL,-1);
  517.    GT_RefreshWindow(winfo->Window,NULL);
  518.    return(0);
  519. }         ///
  520.  
  521. static void FreeStopGui(struct WinInfo *winfo,int backup)                       ///
  522. {
  523.    winfo->Render=0;
  524.    if(backup) {
  525.       winfo->Mode=MODE_BACKUP;
  526.       FindCustom(winfo,winfo->Box);
  527.       winfo->Box->Dim.Flags|=BOXFLG_BACKUP;
  528.    }
  529.    winfo->Mode=MODE_FREE;
  530.    FindCustom(winfo,winfo->Box);
  531.  
  532.    if(winfo->GList) {
  533.       RemoveGList(winfo->Window,winfo->GList,-1);
  534.       FreeGadgets(winfo->GList);
  535.    }
  536.    FreeVisualInfo(winfo->Visual);
  537. } ///
  538. void FreeGui(struct WinInfo *winfo)
  539. {
  540.    FreeStopGui(winfo,0);
  541. }
  542. void StopGui(struct WinInfo *winfo)
  543. {
  544.    FreeStopGui(winfo,1);
  545. }
  546.  
  547. int RenderSubGui(struct WinInfo *winfo,                              ///
  548.                  int left,int top,int width, int height)
  549. {
  550.    if(!(winfo->Box->Dim.Flags & BOXFLG_INITED)) {
  551.       InitGui(winfo,winfo->Box);
  552.       winfo->Box->Dim.Flags|=BOXFLG_INITED;
  553.    }
  554.    if(MakeGuiGadget(winfo,winfo->Box,left,top,width,height)) return(1);
  555.  
  556.    return(0);
  557. } ///
  558. int ResizeSubGui(struct WinInfo *winfo,                              ///
  559.                  int left, int top,int width,int height)
  560. {
  561.    if(MakeGuiGadget(winfo,winfo->Box,left,top,width,height)) return(1);
  562.  
  563.    return(0);
  564. } ///
  565. int RefreshSubGui(struct WinInfo *winfo,int left,int top,int width,int height) ///
  566. {
  567.    winfo->Mode=MODE_REFRESH;
  568.    return(MakeGuiGadget(winfo,winfo->Box,left,top,width,height));
  569. } ///
  570. void FreeSubGui(struct WinInfo *winfo)                               ///
  571. {
  572.    winfo->Mode=MODE_FREE;
  573.    FindCustom(winfo,winfo->Box);
  574. }                                         ///
  575.  
  576. int SubGui(struct WinInfo *parent, struct WinInfo *winfo,            ///
  577.                   int left,int top,int width, int height)
  578. {
  579.    int ret=0;
  580.  
  581.    memcpy((void *)(((ULONG)winfo)+2*sizeof(void *)),
  582.           (void *)(((ULONG)parent)+2*sizeof(void *)),
  583.           sizeof(struct WinInfo)-2*sizeof(void *));
  584.  
  585.    switch(parent->Mode) {
  586.  
  587.       case MODE_NEW:     ret=RenderSubGui(winfo,left,top,width,height);
  588.                          winfo->Box->Dim.Flags&=~BOXFLG_BACKUP;
  589.                          break;
  590.       case MODE_RESIZE:  ret=ResizeSubGui(winfo,left,top,width,height);
  591.                          winfo->Box->Dim.Flags&=~BOXFLG_BACKUP;
  592.                          break;
  593.       case MODE_REFRESH: ret=RefreshSubGui(winfo,left,top,width,height);
  594.                          break;
  595.       case MODE_FREE:    FreeSubGui(winfo);
  596.                          break;
  597.       case MODE_RESTORE:
  598.                          FindCustom(winfo,winfo->Box);
  599.                          break;
  600.       case MODE_BACKUP:  ret=BackupGui(winfo,winfo->Box);
  601.                          FindCustom(winfo,winfo->Box);
  602.                          winfo->Box->Dim.Flags|=BOXFLG_BACKUP;
  603.                          break;
  604.    }
  605.    parent->Prev=winfo->Prev;
  606.    return(ret);
  607. }  ///
  608.